home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 126-150 / disk_147 / sys / bsd / bsd.zoo / fileio.c next >
C/C++ Source or Header  |  1988-07-25  |  8KB  |  384 lines

  1. /*
  2.  *        bsd (4.2, others?), Sun (3.2, ?) and Ultrix-32 (?) file I/O.
  3.  */
  4. #include    "def.h"
  5.  
  6. static    FILE    *ffp;
  7. extern    char    *getenv(), *strncpy();
  8. char    *adjustname();
  9.  
  10. /*
  11.  * Open a file for reading.
  12.  */
  13. ffropen(fn) char *fn; {
  14.     if ((ffp=fopen(fn, "r")) == NULL)
  15.         return (FIOFNF);
  16.     return (FIOSUC);
  17. }
  18.  
  19. /*
  20.  * Open a file for writing.
  21.  * Return TRUE if all is well, and
  22.  * FALSE on error (cannot create).
  23.  */
  24. ffwopen(fn) char *fn; {
  25.     if ((ffp=fopen(fn, "w")) == NULL) {
  26.         ewprintf("Cannot open file for writing");
  27.         return (FIOERR);
  28.     }
  29.     return (FIOSUC);
  30. }
  31.  
  32. /*
  33.  * Close a file.
  34.  * Should look at the status.
  35.  */
  36. ffclose() {
  37.     (VOID) fclose(ffp);
  38.     return (FIOSUC);
  39. }
  40.  
  41. /*
  42.  * Write a buffer to the already
  43.  * opened file. bp points to the
  44.  * buffer. Return the status.
  45.  * Check only at the newline and
  46.  * end of buffer.
  47.  */
  48. ffputbuf(bp)
  49. BUFFER *bp;
  50. {
  51.     register char *cp;
  52.     register char *cpend;
  53.     register LINE *lp;
  54.     register LINE *lpend;
  55.  
  56.     lpend = bp->b_linep;
  57.     lp = lforw(lpend);
  58.     do {
  59.     cp = <ext(lp)[0];        /* begining of line    */
  60.     cpend = &cp[llength(lp)];    /* end of line        */
  61.     while(cp != cpend) {
  62.         putc(*cp, ffp);
  63.         cp++;    /* putc may evalualte arguments more than once */
  64.     }
  65.     lp = lforw(lp);
  66.     if(lp == lpend) break;        /* no implied newline on last line */
  67.     putc('\n', ffp);
  68.     } while(!ferror(ffp));
  69.     if(ferror(ffp)) {
  70.     ewprintf("Write I/O error");
  71.     return FIOERR;
  72.     }
  73.     return FIOSUC;
  74. }
  75.  
  76. /*
  77.  * Read a line from a file, and store the bytes
  78.  * in the supplied buffer. Stop on end of file or end of
  79.  * line.  When FIOEOF is returned, there is a valid line
  80.  * of data without the normally implied \n.
  81.  */
  82. ffgetline(buf, nbuf, nbytes)
  83. register char    *buf;
  84. register int    nbuf;
  85. register int    *nbytes;
  86. {
  87.     register int    c;
  88.     register int    i;
  89.  
  90.     i = 0;
  91.     while((c = getc(ffp))!=EOF && c!='\n') {
  92.         buf[i++] = c;
  93.         if (i >= nbuf) return FIOLONG;
  94.     }
  95.     if (c == EOF  && ferror(ffp) != FALSE) {
  96.         ewprintf("File read error");
  97.         return FIOERR;
  98.     }
  99.     *nbytes = i;
  100.     return c==EOF ? FIOEOF : FIOSUC;
  101. }
  102.  
  103. #ifndef NO_BACKUP
  104. /*
  105.  * Rename the file "fname" into a backup
  106.  * copy. On Unix the backup has the same name as the
  107.  * original file, with a "~" on the end; this seems to
  108.  * be newest of the new-speak. The error handling is
  109.  * all in "file.c". The "unlink" is perhaps not the
  110.  * right thing here; I don't care that much as
  111.  * I don't enable backups myself.
  112.  */
  113. fbackupfile(fn) char *fn; {
  114.     register char    *nname;
  115.     char        *malloc();
  116.  
  117.     if ((nname=malloc((unsigned)(strlen(fn)+1+1))) == NULL) {
  118.         ewprintf("Can't get %d bytes", strlen(fn) + 1);
  119.         return (ABORT);
  120.     }
  121.     (void) strcpy(nname, fn);
  122.     (void) strcat(nname, "~");
  123.     (void) unlink(nname);            /* Ignore errors.    */
  124.     if (rename(fn, nname) < 0) {
  125.         free(nname);
  126.         return (FALSE);
  127.     }
  128.     free(nname);
  129.     return (TRUE);
  130. }
  131. #endif
  132.  
  133. /*
  134.  * The string "fn" is a file name.
  135.  * Perform any required appending of directory name or case adjustments.
  136.  * If NO_DIR is not defined, the same file should be refered to even if the
  137.  * working directory changes.
  138.  */
  139. #ifdef SYMBLINK
  140. #include <sys/types.h>
  141. #include <sys/stat.h>
  142. #ifndef MAXSYMLINKS
  143. #define MAXSYMLINKS 8        /* maximum symbolic links to follow */
  144. #endif
  145. #endif
  146. #include <pwd.h>
  147. #ifndef NO_DIR
  148. extern char *wdir;
  149. #endif
  150.  
  151. char *adjustname(fn)
  152. register char *fn;
  153. {
  154.     register char *cp;
  155.     static char fnb[NFILEN];
  156.     struct passwd *pwent;
  157. #ifdef    SYMBLINK
  158.     struct stat statbuf;
  159.     int i, j;
  160.     char linkbuf[NFILEN];
  161. #endif
  162.  
  163.     switch(*fn) {
  164.         case '/':
  165.         cp = fnb;
  166.         *cp++ = *fn++;
  167.         break;
  168.     case '~':
  169.         fn++;
  170.         if(*fn == '/' || *fn == '\0') {
  171.         (VOID) strcpy(fnb, getenv("HOME"));
  172.         cp = fnb + strlen(fnb);
  173.             if(*fn) fn++;
  174.         break;
  175.         } else {
  176.         cp = fnb;
  177.         while(*fn && *fn != '/') *cp++ = *fn++;
  178.         *cp = '\0';
  179.         if((pwent = getpwnam(fnb)) != NULL) {
  180.             (VOID) strcpy(fnb, pwent->pw_dir);
  181.             cp = fnb + strlen(fnb);
  182.             break;
  183.         } else {
  184.             fn -= strlen(fnb) + 1;
  185.             /* can't find ~user, continue to default case */
  186.         }
  187.         }
  188.     default:
  189. #ifndef    NODIR
  190.         strcpy(fnb, wdir);
  191.         cp = fnb + strlen(fnb);
  192.         break;
  193. #else
  194.         return fn;                /* punt */
  195. #endif
  196.     }
  197.     if(cp != fnb && cp[-1] != '/') *cp++ = '/';
  198.     while(*fn) {
  199.         switch(*fn) {
  200.         case '.':
  201.         switch(fn[1]) {
  202.                 case '\0':
  203.                 *--cp = '\0';
  204.                 return fnb;
  205.                 case '/':
  206.                     fn += 2;
  207.                 continue;
  208.             case '.':
  209.                 if(fn[2]=='/' || fn[2] == '\0') {
  210. #ifdef SYMBLINK
  211.                 cp[-1] = '\0';
  212.                 for(j = MAXSYMLINKS; j-- && 
  213.                         lstat(fnb, &statbuf) != -1 && 
  214.                         (statbuf.st_mode&S_IFMT) == S_IFLNK &&
  215.                         (i = readlink(fnb, linkbuf, sizeof linkbuf))
  216.                     != -1 ;) {
  217.                 if(linkbuf[0] != '/') {
  218.                     --cp;
  219.                     while(cp > fnb && *--cp != '/') {}
  220.                     ++cp;
  221.                     (VOID) strncpy(cp, linkbuf, i);
  222.                     cp += i;
  223.                 } else {
  224.                     (VOID) strncpy(fnb, linkbuf, i);
  225.                     cp = fnb + i;
  226.                 }
  227.                 if(cp[-1]!='/') *cp++ = '\0';
  228.                 else cp[-1] = '\0';
  229.                 }
  230.                 cp[-1] = '/';
  231. #endif
  232.                 --cp;
  233.                 while(cp > fnb && *--cp != '/') {}
  234.                 ++cp;
  235.                 if(fn[2]=='\0') {
  236.                     *--cp = '\0';
  237.                     return fnb;
  238.                 }
  239.                     fn += 3;
  240.                     continue;
  241.                 }
  242.                 break;
  243.             default:
  244.                 break;
  245.             }
  246.         break;
  247.         case '/':
  248.             fn++;
  249.             continue;
  250.         default:
  251.             break;
  252.     }
  253.     while(*fn && (*cp++ = *fn++) != '/') {}
  254.     }
  255.     if(cp[-1]=='/') --cp;
  256.     *cp = '\0';
  257.     return fnb;
  258. }
  259.  
  260. #ifndef NO_STARTUP
  261. #include <sys/file.h>
  262. /*
  263.  * Find a startup file for the user and return its name. As a service
  264.  * to other pieces of code that may want to find a startup file (like
  265.  * the terminal driver in particular), accepts a suffix to be appended
  266.  * to the startup file name.
  267.  */
  268. char *
  269. startupfile(suffix)
  270. char *suffix;
  271. {
  272.     register char    *file;
  273.     static char    home[NFILEN];
  274.     char        *getenv();
  275.  
  276.     if ((file = getenv("HOME")) == NULL) goto notfound;
  277.     if (strlen(file)+7 >= NFILEN - 1) goto notfound;
  278.     (VOID) strcpy(home, file);
  279.     (VOID) strcat(home, "/.mg");
  280.     if (suffix != NULL) {
  281.         (VOID) strcat(home, "-");
  282.         (VOID) strcat(home, suffix);
  283.     }
  284.     if (access(home, F_OK ) == 0) return home;
  285.  
  286. notfound:
  287. #ifdef    STARTUPFILE
  288.     file = STARTUPFILE;
  289.     if (suffix != NULL) {
  290.         (VOID) strcpy(home, file);
  291.         (VOID) strcat(home, "-");
  292.         (VOID) strcat(home, suffix);
  293.         file = home;
  294.     }
  295.     if (access(file, F_OK ) == 0) return file;
  296. #endif
  297.  
  298.     return NULL;
  299. }
  300. #endif
  301.  
  302. #ifndef NO_DIRED
  303. #include <sys/wait.h>
  304. #include "kbd.h"
  305.  
  306. copy(frname, toname)
  307. char *frname, *toname;
  308. {
  309.     int pid;
  310.     char *eargv[3];
  311.     union wait status;
  312.  
  313.     if(pid = vfork()) {
  314.     if(pid == -1)    return    -1;
  315.     eargv[0] = frname;
  316.     eargv[1] = toname;
  317.     eargv[2] = NULL;
  318.     execve("cp", eargv, (char **)NULL);
  319.     _exit(1);    /* shouldn't happen */
  320.     }
  321.     while(wait(&status) != pid) {}
  322.     return status.w_status == 0;
  323. }
  324.  
  325. BUFFER *dired_(dirname)
  326. char *dirname;
  327. {
  328.     register BUFFER *bp;
  329.     char line[256];
  330.     BUFFER *findbuffer();
  331.     FILE *dirpipe;
  332.     FILE *popen();
  333.  
  334.     if((dirname = adjustname(dirname)) == NULL) {
  335.     ewprintf("Bad directory name");
  336.     return NULL;
  337.     }
  338.     if(dirname[strlen(dirname)-1] != '/') (VOID) strcat(dirname, "/");
  339.     if((bp = findbuffer(dirname)) == NULL) {
  340.     ewprintf("Could not create buffer");
  341.     return NULL;
  342.     }
  343.     if(bclear(bp) != TRUE) return FALSE;
  344.     (VOID) strcpy(line, "ls -al ");
  345.     (VOID) strcpy(&line[7], dirname);
  346.     if((dirpipe = popen(line, "r")) == NULL) {
  347.     ewprintf("Problem opening pipe to ls");
  348.     return NULL;
  349.     }
  350.     line[0] = line[1] = ' ';
  351.     while(fgets(&line[2], 254, dirpipe) != NULL) {
  352.     line[strlen(line) - 1] = '\0';        /* remove ^J    */
  353.     (VOID) addline(bp, line);
  354.     }
  355.     if(pclose(dirpipe) == -1) {
  356.     ewprintf("Problem closing pipe to ls");
  357.     return NULL;
  358.     }
  359.     bp->b_dotp = lforw(bp->b_linep);        /* go to first line */
  360.     (VOID) strncpy(bp->b_fname, dirname, NFILEN);
  361.     if((bp->b_modes[0] = name_mode("dired")) == NULL) {
  362.     bp->b_modes[0] = &map_table[0];
  363.     ewprintf("Could not find mode dired");
  364.     return NULL;
  365.     }
  366.     bp->b_nmodes = 0;
  367.     return bp;
  368. }
  369.  
  370. d_makename(lp, fn)
  371. register LINE *lp;
  372. register char *fn;
  373. {
  374.     register char *cp;
  375.  
  376.     if(llength(lp) <= 47) return ABORT;
  377.     (VOID) strcpy(fn, curbp->b_fname);
  378.     cp = fn + strlen(fn);
  379.     bcopy(&lp->l_text[47], cp, llength(lp) - 47);
  380.     cp[llength(lp) - 47] = '\0';
  381.     return lgetc(lp, 2) == 'd';
  382. }
  383. #endif
  384.